#ifndef __SUBSYSTEM_PLANT_BLOCK_BEHAVIOR_H__
#define __SUBSYSTEM_PLANT_BLOCK_BEHAVIOR_H__

#include <set>
#include <mutex>
#include "Engine/Point3.hpp"
#include "Subsystems/BlockBehaviors/SubsystemPollableBlockBehavior.hpp"
#include "GameLock.hpp"


using namespace PocketSurvival::Engine;

namespace PocketSurvival
{
    class SubsystemTimeOfDay;
    class SubsystemTerrain;
    class SubsystemGameInfo;

    // 植物行为，包括农作物生长
    class SubsystemPlantBlockBehavior : public SubsystemPollableBlockBehavior
    {
    protected:
        struct Replacement
        {
            constexpr inline Replacement() : requiredValue(0), value(0) {}
            constexpr inline Replacement(int32_t theRequiredValue, int32_t theValue) : requiredValue(theRequiredValue), value(theValue) {}
            int32_t requiredValue;
            int32_t value;
        };

    protected:
        SubsystemTimeOfDay *m_timeOfDay;
        SubsystemTerrain *m_terrain;
        SubsystemGameInfo *m_gameInfo;

        std::map<Point3, Replacement> m_toReplace;
        SpinLock m_toReplaceLock;

    public:
        SubsystemPlantBlockBehavior();
        virtual void onPoll(int32_t value, int32_t x, int32_t y, int32_t z) override;
        virtual void onNeighborBlockChanged(int32_t x, int32_t y, int32_t z, int32_t neighborX, int32_t neighborY, int32_t neighborZ) override;
        virtual void update(float dt) override;

        void growTallGrass(int32_t value, int32_t x, int32_t y, int32_t z);
        void growFlower(int32_t value, int32_t x, int32_t y, int32_t z);
        void growRye(int32_t value, int32_t x, int32_t y, int32_t z);
        void growCotton(int32_t value, int32_t x, int32_t y, int32_t z);
        void growPumpkin(int32_t value, int32_t x, int32_t y, int32_t z);

        virtual void load(const nlohmann::json& json) override;
        virtual const std::string& getName() const override;
        virtual SubUpdateType getUpdateType() override;
    };
    
}

#endif
